Practical 3

Writing R Functions

Authors

Team member 1

Team member 2

Published

December 16, 2024

Download the raw document here

This activity will ask you to write several small functions, then use them to unscramble a message.

Some advice 🤝
  • Work in groups, maximum 2!
  • Google is your friend! If an error is confusing, copy it into Google and see what other people are saying. If you don’t know how to do something, search for it. You can use AI to help you understand code as well, but be critical of the outputs and always double check that it works.
  • Just because there is no error message, it doesn’t mean everything went smoothly. Use the console to check each step and make sure you have accomplished what you wanted to accomplish.
  • See more tips on error handling here.
  • Document your process! Use the empty code chunks set-up for you. If you need more remember the keyboard shortcut is CTRL+ALT+I or CMD+ALT+I.

Part One: Create your functions

Many of the functions have been started for you below, but none of them are complete as-is.

  1. Write a function called divide_and_round(), which takes a number or vector of numbers, divides them all by their smallest value, and rounds the results to the nearest whole number.

Test it by running the code below the function.

divide_and_round <- function(nums){
  
  my_min <- min(nums, na.rm = TRUE)
  divided <- nums/my_min
  
}


test <- c(1:5, NA)

divide_and_round(test)
  1. Write a function called no_nines_or_twelves(), which takes a number or vector of numbers and returns TRUE if the number is NOT divisible by 9 or 12, FALSE otherwise.
no_nines_or_twelves <- function(nums){
  
  check <- !(nums %% 9 == 0 | nums %% 12 == 0)
  
}

test <- c(1:10*5, NA)

no_nines_or_twelves(test)
  1. Write a function called every_other() which takes a vector and returns every other value in the vector.
Hint 🔍

You could achieve this with a for-loop but there are definitely more efficient ways to do it!

Include an optional argument called “start” which lets you choose where to start skipping; that is, if start = 1, we return the 1st value, 3rd, 5th, etc. and if start = 2, we return the 2nd, 4th, 6th, etc.

every_other <- function(vec){
  
  if(start == 2){

    
  } else if(start == 1) {
    
    
    
    
  }
  
}

test <- c(1:10)

every_other(test)
Error in start == 2: comparison (==) is possible only for atomic and list types
every_other(test, start = 2)
Error in every_other(test, start = 2): unused argument (start = 2)
  1. Write a function called shorten() which takes a vector and keeps dropping the first value, until the sum of the vector is less than 350 Return the remaining values.
Hint 🔍

You probably want to either use the cumsum() function, or write a while() loop.

Be sure to test your function.

shorten <- function(){

  
}

Part Two: Your functions are the key

  1. Once you have written your four functions correctly, run the following code:
my_vec <- c(39, 1.87, 48, 11, 8, 45, 21, 5, 12, 33, 9, 11, 108, 4, 18, 5, 16, 17, 8, 48, 27, 24, 4, 22, 12, 27, 23, 46, 42, 35, 15, 34, 36, 26, 18, 10, 18.21, 72.04, 36.9, 41.81, 29, 89.75, 34.03, 20.18, 48.74, 15.76, 31.86, 83.6, 43.55, 39.99, 23.55, 8.54, 24.71, 22.02, 9.71, 62.14, 35.46, 16.61, 15.66, 21.29, 30.52, 201.07, 45.81, 7.85, 30.13, 34.14, 22.62, 10.2, 6.02, 30.12, 10.64, 31.72, 24.57, 14.43, 43.37, 89.93, 44.72, 51.32, 13.62, 45.56, 22.96, 7.05, 29.99, 41.38, 26.59, 23.04, 19.82, 50.73, 39.56, 43.79, 30.22, 85.85, 5.78, 78.85, 29.52, 66.27, 44.06, 27.28, 24.43, 64.32, 3.35, 67.45, 46.72, 48.44, 48.65, 33.3, 40.28, 19.04)

my_vec <- every_other(my_vec, start = 2)
Error in every_other(my_vec, start = 2): unused argument (start = 2)
my_vec <- divide_and_round(my_vec)
my_vec <- every_other(my_vec, start = 1)
Error in every_other(my_vec, start = 1): unused argument (start = 1)
my_vec <- shorten(my_vec)
Error in shorten(my_vec): unused argument (my_vec)
my_vec <- my_vec[no_nines_or_twelves(my_vec)]

my_vec <- sort(my_vec)

my_vec
  [1]   1.000000   1.791444   2.139037   2.139037   2.673797   2.673797
  [7]   3.090909   3.219251   3.770053   4.197861   4.278075   4.278075
 [13]   4.566845   4.812834   5.192513   5.347594   5.454545   5.689840
 [19]   5.882353   5.882353   6.417112   6.417112   7.283422   7.716578
 [25]   8.021390   8.374332   8.427807   8.556150   8.882353   9.090909
 [31]   9.625668   9.625668   9.737968  10.181818  10.598930  10.791444
 [37]  11.229947  11.385027  11.764706  11.775401  12.096257  12.278075
 [43]  12.299465  12.320856  12.593583  12.834225  13.064171  13.139037
 [49]  13.213904  13.903743  14.219251  14.438503  14.438503  14.588235
 [55]  15.508021  15.786096  16.037433  16.106952  16.112299  16.160428
 [61]  16.320856  16.962567  17.037433  17.647059  17.807487  18.181818
 [67]  18.197861  18.256684  18.716578  18.962567  19.251337  19.732620
 [73]  20.855615  21.155080  21.385027  21.540107  22.128342  22.358289
 [79]  22.459893  23.192513  23.288770  23.417112  23.561497  23.914439
 [85]  24.064171  24.363636  24.497326  24.598930  24.983957  25.668449
 [91]  25.668449  25.903743  26.016043  26.064171  27.128342  27.443850
 [97]  33.229947  34.395722  35.438503  36.069519  38.524064  42.165775
[103]  44.705882  45.909091  47.994652  48.090909  57.754011 107.524064

If you have done everything correctly, your final vector will be six numbers long. Google these six numbers to find a TV show as your final answer.

Solution 🎉

Write the name of the TV show here.

Upload the .qmd doc and the rendered html to Blackboard (don’t forget to add all your teammates names!). The first team receives an extra point each in class participation 🏃